package com.hjjt.cameralib.cameraengin

import android.content.Context
import android.graphics.Bitmap
import android.util.Log
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner
import com.cloudwalk.android.*
import com.cloudwalk.android.CWDefine.CWEnumCameraDataFormat
import com.cloudwalk.android.CWDefine.CWLivenessErrorCode.CW_LIVENESS_SUCCESS
import com.hjjt.baselib.util.logError
import com.hjjt.cameralib.CameraHelperImpl
import com.hjjt.cameralib.CameraInstance
import com.hjjt.cameralib.data.*
import com.hjjt.cameralib.listener.LiveCheckListener
import com.hjjt.cameralib.opengl.CWGLDisplay
import com.hjjt.cameralib.opengl.GLFrameSurface
import com.hjjt.cameralib.utils.BMPUtil
import com.hjjt.cameralib.utils.RgbToBitmapUtils
import com.hjjt.cameraplugin.CameraEngineConfig
import com.hjjt.cameraplugin.ImageData
import com.hjjt.logger.logger
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import java.lang.ref.WeakReference

/**
 *
 * @ProjectName:    PluginDemo
 * @Package:        com.hjjt.cameralib.cameraengin
 * @ClassName:      云从摄像头
 * @Description:
 * @Author:         孙浩
 * @CreateDate:     2022/5/31 15:49
 */
class CloudWalkCamera : CameraEngine {

    var display: CWGLDisplay? = CWGLDisplay()
    var surfaceView: GLFrameSurface? = null
    val TAG = "YunCongCamera"
    var cameraTag = 0L
    var cameraOpenType: CameraEngineConfig.CameraType =
        CameraEngineConfig.CameraType.CLOUD_WALK_OPEN_ALL
    var streamType: CameraEngineConfig.CameraType =
        CameraEngineConfig.CameraType.CLOUD_WALK_OPEN_VIS
    var firstFrameTime = 0
    override fun init(configPath: String, licensePath: String): Boolean =
        init(configPath, licensePath, null, null)

    override fun init(
        configPath: String,
        licensePath: String,
        openMode: CameraEngineConfig.OpenMode?,
        liveMode: CameraEngineConfig.LiveMode?
    ): Boolean {
        synchronized(this) {
            val model = when (openMode) {
                CameraEngineConfig.OpenMode.CLOUD_WALK_OPEN_MODE_UVC -> CWDefine.CWEnumCameraOpenMode.CW_CAMERA_OPENMODE_UVC
                CameraEngineConfig.OpenMode.CLOUD_WALK_OPEN_MODE_V4L2 -> CWDefine.CWEnumCameraOpenMode.CW_CAMERA_OPENMODE_V4L2
                else -> CWDefine.CWEnumCameraOpenMode.CW_CAMERA_OPENMODE_V4L2
            }
            val liveModel = when (liveMode) {
                CameraEngineConfig.LiveMode.CLOUD_WALK_LIVE_MODE_AUTO -> CWDefine.CWLDEnumLiveMode.CW_LIVEMODE_AUTO
                CameraEngineConfig.LiveMode.CLOUD_WALK_LIVE_MODE_NIR -> CWDefine.CWLDEnumLiveMode.CW_LIVEMODE_NIR
                CameraEngineConfig.LiveMode.CLOUD_WALK_LIVE_MODE_STR -> CWDefine.CWLDEnumLiveMode.CW_LIVEMODE_STR
                CameraEngineConfig.LiveMode.CLOUD_WALK_LIVE_MODE_ACT -> CWDefine.CWLDEnumLiveMode.CW_LIVEMODE_ACT
                else -> CWDefine.CWLDEnumLiveMode.CW_LIVEMODE_AUTO
            }
            val cwRet = CWLiveEngineSDK.instance.cwLDEngine_Init(
                CameraInstance.instance.applicationContext,
                CWPathInfo().apply {
                    configurePath = configPath
                    setLicensePath(licensePath)
                },
                liveModel,
                model
            )
            if (CWDefine.CW_SDK_SUCCESS == cwRet.errorCode.toInt() && 0L != cwRet.obj) {
                cameraTag = cwRet.obj
            }
            logMessage("init", cwRet.errorCode)
            return cwRet.errorCode.toInt() == CWDefine.CW_SDK_SUCCESS
        }
    }

    override fun unInit() {
        synchronized(this) {
            val cwRet = CWLiveEngineSDK.instance.cwLDEngine_UnInit(cameraTag)
            cameraTag = 0L
        }

    }


    override fun getCameraParam(): String {
        synchronized(this) {
            val cwRet = CWLiveEngineSDK.instance.cwLDEngine_GetParam(cameraTag)
            return cwRet.obj
        }
    }

    override fun setParams(params: String): Long {
        synchronized(this) {
            val cwRet = CWLiveEngineSDK.instance.cwLDEngine_SetParam(cameraTag, params)
            logMessage("setParams", cwRet.errorCode)
            return cwRet.errorCode
        }
    }

    override fun startDetect(
        decType: CameraEngineConfig.DetectType,
        timeoutMilliSeconds: Int
    ): Boolean {
        synchronized(this) {
            val type = when (decType) {
                CameraEngineConfig.DetectType.CLOUD_WALK_DEC_TYPE_FACE -> CWDefine.CWEnumDetectType.CW_DECTYPE_FACE
                CameraEngineConfig.DetectType.CLOUD_WALK_DEC_TYPE_LIVENESS -> CWDefine.CWEnumDetectType.CW_DECTYPE_LIVENESS
                CameraEngineConfig.DetectType.CLOUD_WALK_DEC_TYPE_LIVENESS_CONTINUE -> CWDefine.CWEnumDetectType.CW_DECTYPE_LIVENESS_CONTINUE
                else -> CWDefine.CWEnumDetectType.CW_DECTYPE_FACE
            }
            val cwRet =
                CWLiveEngineSDK.instance.cwLDEngine_StartDetect(
                    cameraTag,
                    type,
                    timeoutMilliSeconds
                )
            logMessage("startDetect", cwRet.errorCode)
            if (cwRet.errorCode.toInt() == CW_LIVENESS_SUCCESS) {
                CameraHelperImpl.cameraStartDetect?.invoke()
            } else {
                CameraHelperImpl.cameraOpenError?.invoke("startDetect", cwRet.errorCode.toInt())
            }

            return cwRet.errorCode.toInt() == CW_LIVENESS_SUCCESS
        }
    }

    override fun stopDetect(): Boolean {
        synchronized(this) {
            val success =
                CWLiveEngineSDK.instance.cwLDEngine_StopDetect(cameraTag).errorCode.toInt() == CW_LIVENESS_SUCCESS
            return success
        }
    }

    override fun openCamera(cameraType: CameraEngineConfig.CameraType): Boolean {
        synchronized(this) {
            val type = checkCameraType(cameraType)
            cameraOpenType = cameraType
            val cwRet = CWLiveEngineSDK.instance.cwLDEngine_OpenCamera(cameraTag, type)
            logMessage("openCamera", cwRet.errorCode)
            if (cwRet.errorCode.toInt() != CW_LIVENESS_SUCCESS) {
                CameraHelperImpl.cameraOpenError?.invoke("openCamera", cwRet.errorCode.toInt())
            }
            return cwRet.errorCode.toInt() == CW_LIVENESS_SUCCESS
        }
    }


    override fun closeCamera(cameraType: CameraEngineConfig.CameraType): Boolean {
        synchronized(this) {
            val type = checkCameraType(cameraType)
            val cwRet = CWLiveEngineSDK.instance.cwLDEngine_CloseCamera(cameraTag, type)
            logMessage("closeCamera", cwRet.errorCode)
            return cwRet.errorCode.toInt() == CW_LIVENESS_SUCCESS
        }
    }

    override fun setCameraDataListener(
        cameraType: CameraEngineConfig.CameraType,
        formatType: CameraEngineConfig.FormatDataType,
        drawFaceRect: Boolean, cameraCallBack: ((data: ImageData) -> Unit)?
    ): Boolean {
        synchronized(this) {
            val type = checkCameraType(cameraType)
            if (type == CWDefine.CWLDEnumCamType.CW_CAMERA_OPEN_ALL) {
                throw RuntimeException("不支持 type 为 OPEN_ALL")
            }

            val formatType = checkFormatType(formatType)
            val callBack: CWCameraDataCallback? = if (cameraCallBack == null) {
                null
            } else {
                CWCameraDataCallback { cameraImage,  //图像数据
                                       cameraDevice, //相机数据
                                       _ ->          //用户自定义数据 设置为空了
                    bindSurfaceToRender(cameraImage)
                    cameraCallBack?.invoke(
                        ImageData(
                            cameraImage.data,
                            cameraImage.width.toInt(),
                            cameraImage.height.toInt()
                        )
                    )
                }
            }
            val cwRet = CWLiveEngineSDK.instance.cwLDEngine_SetCameraDataCallback(
                cameraTag,
                type,
                callBack,
                formatType, drawFaceRect, null
            )
            return cwRet.errorCode.toInt() == CW_LIVENESS_SUCCESS
        }
    }

    fun bindSurfaceToRender(
        cameraImage: CWCameraImage,
    ) {
        surfaceView?.let { surface ->
            val format = CWEnumCameraDataFormat.values()[cameraImage.format]
            val type = when (format) {
                CWEnumCameraDataFormat.CW_CAMERA_FRAME_FORMAT_RGB888 -> 1
                CWEnumCameraDataFormat.CW_CAMERA_FRAME_FORMAT_YUV420 -> 0
                CWEnumCameraDataFormat.CW_CAMERA_FRAME_FORMAT_GRAY8 -> 2
                CWEnumCameraDataFormat.CW_CAMERA_FRAME_FORMAT_GRAY16 -> 3
                CWEnumCameraDataFormat.CW_CAMERA_FRAME_FORMAT_GRAY16_8 -> 4
                else -> 0
            }
            Thread {
                display?.render(
                    surface,
                    cameraImage.angle,
                    cameraImage.mirror == 1,
                    cameraImage.data,
                    cameraImage.width.toInt(),
                    cameraImage.height.toInt(),
                    type
                )
            }.start()


        }
    }


    override fun setCameraStreamFormat(
        cameraType: CameraEngineConfig.CameraType,
        formatType: CameraEngineConfig.FormatStreamType,
        width: Int,
        height: Int,
        fps: Int
    ): Boolean {
        val cType = checkCameraType(cameraType)
        val fType = when (formatType) {
            CameraEngineConfig.FormatStreamType.FORMAT_UNKNOWN -> CWDefine.CWEnumCameraStreamFormat.CW_CAMERA_STREAM_FORMAT_UNKNOWN
            CameraEngineConfig.FormatStreamType.FORMAT_RGB888 -> CWDefine.CWEnumCameraStreamFormat.CW_CAMERA_STREAM_FORMAT_RGB888
            CameraEngineConfig.FormatStreamType.FORMAT_MJPEG -> CWDefine.CWEnumCameraStreamFormat.CW_CAMERA_STREAM_FORMAT_MJPEG
            CameraEngineConfig.FormatStreamType.FORMAT_YUY2 -> CWDefine.CWEnumCameraStreamFormat.CW_CAMERA_STREAM_FORMAT_YUY2
            CameraEngineConfig.FormatStreamType.FORMAT_H264 -> CWDefine.CWEnumCameraStreamFormat.CW_CAMERA_STREAM_FORMAT_H264
            CameraEngineConfig.FormatStreamType.FORMAT_H265 -> CWDefine.CWEnumCameraStreamFormat.CW_CAMERA_STREAM_FORMAT_H265
            CameraEngineConfig.FormatStreamType.FORMAT_GRAY -> CWDefine.CWEnumCameraStreamFormat.CW_CAMERA_STREAM_FORMAT_GRAY
            CameraEngineConfig.FormatStreamType.FORMAT_RGB888_GRAY16 -> CWDefine.CWEnumCameraStreamFormat.CW_CAMERA_STREAM_FORMAT_RGB888_GRAY16
            CameraEngineConfig.FormatStreamType.FORMAT_GRAY8_16 -> CWDefine.CWEnumCameraStreamFormat.CW_CAMERA_STREAM_FORMAT_GRAY8_16
            else -> CWDefine.CWEnumCameraStreamFormat.CW_CAMERA_STREAM_FORMAT_UNKNOWN
        }
        val cwRet = CWLiveEngineSDK.instance.cwLDEngine_SetCameraStreamFormat(
            cameraTag,
            cType,
            fType,
            width,
            height,
            fps
        )
        logMessage("setCameraStreamFormat", cwRet.errorCode)
        return cwRet.errorCode.toInt() == CW_LIVENESS_SUCCESS
    }

    override fun setCameraRotateAndMirror(
        cameraType: CameraEngineConfig.CameraType,
        angle: CameraEngineConfig.Angle,
        isMirror: Boolean
    ): Boolean {
        val type = checkCameraType(cameraType)
        val angle = when (angle) {
            CameraEngineConfig.Angle.ANGLE_0 -> CWDefine.CWEnumCameraDataAngle.CW_CAMERA_ANGLE_0
            CameraEngineConfig.Angle.ANGLE_90 -> CWDefine.CWEnumCameraDataAngle.CW_CAMERA_ANGLE_90
            CameraEngineConfig.Angle.ANGLE_180 -> CWDefine.CWEnumCameraDataAngle.CW_CAMERA_ANGLE_180
            CameraEngineConfig.Angle.ANGLE_270 -> CWDefine.CWEnumCameraDataAngle.CW_CAMERA_ANGLE_270
            else -> CWDefine.CWEnumCameraDataAngle.CW_CAMERA_ANGLE_0
        }
        val mirror =
            if (isMirror) CWDefine.CWEnumCameraDataMirror.CW_CAMERA_MIRROR_HOR else CWDefine.CWEnumCameraDataMirror.CW_CAMERA_MIRROR_NONE
        val cwRet =
            CWLiveEngineSDK.instance.cwLDEngine_SetCameraRotateAndMirror(
                cameraTag,
                type,
                angle,
                mirror
            )
        logMessage("setCameraRotateAndMirror", cwRet.errorCode)
        return cwRet.errorCode.toInt() == CW_LIVENESS_SUCCESS
    }

    override fun openOrCloseStream(
        cameraType: CameraEngineConfig.CameraType,
        streamOn: Boolean
    ): Boolean {
        synchronized(this) {
            Log.e(TAG, "openOrCloseStream: open:$streamOn,")
            var success = false
            val type = checkCameraType(cameraType)
            streamType = cameraType
            val cwRet =
                CWLiveEngineSDK.instance.cwLDEngine_CameraStreamOn(
                    cameraTag,
                    type,
                    streamOn
                )
            logMessage("opnOrCloseStream", cwRet.errorCode)
            success = cwRet.errorCode.toInt() == CW_LIVENESS_SUCCESS
            if (cwRet.errorCode.toInt() != CW_LIVENESS_SUCCESS) {
                CameraHelperImpl.cameraOpenError?.invoke(
                    "openOrCloseStream , ${streamOn}",
                    cwRet.errorCode.toInt()
                )
            }

            Log.e(TAG, "openOrCloseStream: open:$streamOn,complete")
            return success
        }
    }

    override fun getCameraStatus(cameraType: CameraEngineConfig.CameraType): CameraEngineConfig.CameraStatus {
        synchronized(this) {
            val type = checkCameraType(cameraType)
            val cwRet = CWLiveEngineSDK.instance.cwLDEngine_GetCameraStatus(cameraTag, type)
            return when (cwRet.obj) {
                CWDefine.CWEnumCameraStatus.CW_CAMERA_STATUS_UNKNOWN -> CameraEngineConfig.CameraStatus.STATUS_UNKNOWN
                CWDefine.CWEnumCameraStatus.CW_CAMERA_STATUS_OPENED -> CameraEngineConfig.CameraStatus.STATUS_OPENED
                CWDefine.CWEnumCameraStatus.CW_CAMERA_STATUS_FORMATSET -> CameraEngineConfig.CameraStatus.STATUS_FORMATSET
                CWDefine.CWEnumCameraStatus.CW_CAMERA_STATUS_STREAMON -> CameraEngineConfig.CameraStatus.STATUS_STREAMON
                CWDefine.CWEnumCameraStatus.CW_CAMERA_STATUS_CLOSED -> CameraEngineConfig.CameraStatus.STATUS_CLOSED
                CWDefine.CWEnumCameraStatus.CW_CAMERA_STATUS_LOST -> CameraEngineConfig.CameraStatus.STATUS_LOST
                else -> CameraEngineConfig.CameraStatus.STATUS_UNKNOWN
            }
        }
    }

    override fun captureImage(
        cameraType: CameraEngineConfig.CameraType,
        imageType: CameraEngineConfig.CaptureImageFormat,
        isBase64: Boolean,
        angle: CameraEngineConfig.Angle
    ): ImageData? {
        synchronized(this) {
            val type = checkCameraType(cameraType)
            val imgType = checkImgType(imageType)
            val cwRet =
                CWLiveEngineSDK.instance.cwLDEngine_CaptureImage(cameraTag, type, imgType, isBase64)
            if (cwRet.errorCode.toInt() != CW_LIVENESS_SUCCESS) return null
            val cwCaptureImage = cwRet.obj
            val data = ByteArray(cwCaptureImage.data.capacity())
            cwCaptureImage.data.clear()
            cwCaptureImage.data[data]
            val mCWLDImage = CWLDImage(
                data,
                cwCaptureImage.width,
                cwCaptureImage.height,
                CWEnumCameraDataFormat.CW_CAMERA_FRAME_FORMAT_RGB888,
                false
            )
            val bgr2Bitmap: Bitmap? =
                RgbToBitmapUtils.bgr2Bitmap(mCWLDImage.data, mCWLDImage.width, mCWLDImage.height)
                    .run {
                        val degree: Int = when (angle) {
                            CameraEngineConfig.Angle.ANGLE_0 -> 180
                            CameraEngineConfig.Angle.ANGLE_90 -> -180
                            CameraEngineConfig.Angle.ANGLE_180 -> 180
                            CameraEngineConfig.Angle.ANGLE_270 -> -180
                        }
                        val bmp = BMPUtil.rotateBitmapByDegree(
                            this,
                            degree
                        )
                        bmp
                    }
            logMessage("captureImage", cwRet.errorCode)
            return cwRet.obj?.run {
                ImageData(cwCaptureImage.data, width, height).apply {
                    bgr2Bitmap?.run {
                        setBitmap(this)
                    }
                }
            }
        }
    }


    override fun getDetectedImage(
        cameraType: CameraEngineConfig.CameraType,
        imageType: CameraEngineConfig.CaptureImageFormat,
        isBase64: Boolean,
        liveType: CameraEngineConfig.LiveImageType
    ): ImageData? {
        synchronized(this) {
            val type = checkCameraType(cameraType)
            val imgType = checkImgType(imageType)
            if (imgType == CWDefine.CWEnumImageFormat.CW_IMAGE_FORMAT_RAW) {
                throw RuntimeException("图像格式不能为RAW")
            }
            val lType = when (liveType) {
                CameraEngineConfig.LiveImageType.TYPE_FULL -> CWDefine.CWLDEnumLiveImageType.CW_LIVE_IMAGE_TYPE_FULL
                CameraEngineConfig.LiveImageType.TYPE_FACE -> CWDefine.CWLDEnumLiveImageType.CW_LIVE_IMAGE_TYPE_FACE
                else -> CWDefine.CWLDEnumLiveImageType.CW_LIVE_IMAGE_TYPE_FULL
            }
            val cwRet = CWLiveEngineSDK.instance.cwLDEngine_GetDetectedImage(
                cameraTag,
                type,
                imgType,
                isBase64,
                lType
            )
            logMessage("getDetectedImage", cwRet.errorCode)
            return cwRet.obj?.run {
                ImageData(data, width, height)
            }
        }
    }

    override fun getFeatureLength(): Int {
        synchronized(this) {
            val cwRet = CWLiveEngineSDK.instance.cwLDEngine_GetFeatureLength(cameraTag)
            logMessage("getFeatureLength", cwRet.errorCode)
            return if (cwRet.errorCode.toInt() == CW_LIVENESS_SUCCESS) cwRet.obj else -1
        }
    }

    override fun getFeature(
        rect: FaceRect,
        imgData: ByteArray,
        dataLength: Int,
        width: Int,
        height: Int,
        isBase64: Boolean,
        formatType: CameraEngineConfig.FormatDataType,
        onlyKeypt: Boolean
    ): FeatureData? {
        synchronized(this) {
            val fType = checkFormatType(formatType)
            val cwRet = CWLiveEngineSDK.instance.cwLDEngine_GetFeature(
                cameraTag,
                CWLDImage(imgData, width, height, fType, isBase64),
                CWFaceRect().apply {
                    setWidth(rect.width)
                    setHeight(rect.height)
                    x = rect.left
                    y = rect.top
                },
                onlyKeypt
            )
            val result = cwRet.obj
            if (cwRet.errorCode.toInt() != CW_LIVENESS_SUCCESS) {
                return null
            }
            logMessage("getFeature", cwRet.errorCode)
            return FeatureData(
                info = FeatureInfo(
                    featreData = result.recogInfo.feature_data,
                    featureLength = result.recogInfo.feature_length,
                    keyptNum = result.recogInfo.keypt_num,
                    point = result.recogInfo.key_points.map {
                        FeatureFacePoint(it.x, it.y)
                    }.toList(),
                    alignedFace = FeatureFaceAligned(
                        data = result.recogInfo.aligned_face.data,
                        width = result.recogInfo.aligned_face.width,
                        height = result.recogInfo.aligned_face.height,
                        channels = result.recogInfo.aligned_face.channels,
                    )
                ),
                faceRect = result.faceRect.map {
                    FaceRect(it.x, it.y, it.width, it.height)
                }.toList(),
                faceNum = result.faceNum
            )
        }
    }

    override fun compareFeature(
        proboFeature: ByteArray,
        filedFeature: ByteArray,
        filedNum: Int
    ): FloatArray? {
        synchronized(this) {
            val cwRet = CWLiveEngineSDK.instance.cwLDEngine_CompareFeature(
                cameraTag,
                proboFeature,
                filedFeature,
                filedNum
            )
            logMessage("compareFeature", cwRet.errorCode)
            return if (cwRet.errorCode.toInt() == CW_LIVENESS_SUCCESS) {
                cwRet.obj
            } else {
                null
            }
        }
    }

    override fun initSurfaceView(surfaceView: GLFrameSurface?) {
        if (surfaceView == null) {
            display?.release()
            display = null
        } else {
            if (display == null) display = CWGLDisplay()
        }
        this.surfaceView = surfaceView
    }

    override fun bindToLifecycle(lifecycleOwner: LifecycleOwner) {
        lifecycleOwner.lifecycle.addObserver(object : LifecycleEventObserver {
            override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
                if (event == Lifecycle.Event.ON_DESTROY) {
                    logError("GLSurfaceFragment:onDestroy event")
                    openOrCloseStream(streamType, false)
                    stopDetect()
//                    close()
                    surfaceView = null
                    display?.release()
//                    closeCamera(cameraOpenType)
                    display = null

//                    unInit()
                } else if (event == Lifecycle.Event.ON_PAUSE) {
                }
            }
        })
    }

    override fun close() {
        openOrCloseStream(streamType, false)
        stopDetect()
        closeCamera(cameraOpenType)
//        unInit()
    }

    override fun setPreviewCallBack(previewCallBack: () -> Unit): Boolean {
        synchronized(this) {
            val cwRet = CWLiveEngineSDK.instance.cwLDEngine_SetCameraDataCallback(
                cameraTag,
                CWDefine.CWLDEnumCamType.CW_CAMERA_OPEN_NIS,
                { cwImage, cwCamera, p2 ->
                    previewCallBack.invoke()
                },
                CWDefine.CWEnumCameraDataFormat.CW_CAMERA_FRAME_FORMAT_RGB888,
                true,
                null
            )
            return cwRet.errorCode.toInt() == CW_LIVENESS_SUCCESS
        }
    }

    override fun setEventCallBack(liveCheckListener: LiveCheckListener): Boolean {
        synchronized(this) {
            val cwRet = CWLiveEngineSDK.instance.cwLDEngine_SetEventCallback(
                cameraTag,
                { errorCode, //错误码
                  timestamp, //检测时间戳
                  cwLiveImage,//可见光图像
                  cwDetectorCallbackData,//回调数据
                  userParams -> //自定参数 方法写为空了
                    when (CWDefine.CWEventType.values()[cwDetectorCallbackData.detectEventType]) {
                        CWDefine.CWEventType.CW_EVENT_UNKNOWN -> {}
                        CWDefine.CWEventType.CW_EVENT_FACE_DETECT -> {}
                        CWDefine.CWEventType.CW_EVENT_LIVE_DETECT -> {
                            if (errorCode.toInt() == CloudWalkErrorCode.CW_FACE_LIV_IS_LIVE) {
                                cwDetectorCallbackData.faceDetectData
                                liveCheckListener.faceIsLive(
                                    ImageData(
                                        cwLiveImage.data,
                                        cwLiveImage.width.toInt(),
                                        cwLiveImage.height.toInt()
                                    ).apply {
                                        cwLiveImage.data.clear()
                                        val bytes = ByteArray(cwLiveImage.data.capacity())
                                        cwLiveImage.data.get(bytes)
                                        val bmp = RgbToBitmapUtils.bgr2Bitmap(
                                            bytes,
                                            cwLiveImage.width.toInt(),
                                            cwLiveImage.height.toInt()
                                        )
                                        setBitmap(bmp)
                                    }
                                )
                            }
                            if (errorCode.toInt() == CloudWalkErrorCode.CW_FACE_LIV_IS_UNLIVE_ERR) {
                                liveCheckListener.faceIsUnLive()
                            }
                            if (errorCode.toInt() == CloudWalkErrorCode.CW_FACE_LIV_POSE_DET_FAIL_ERR) {
                                liveCheckListener.changePose()
                            }
                        }
                    }
                },
                null
            )
            logMessage("setEventCallBack", cwRet.errorCode)
            return cwRet.errorCode.toInt() == CW_LIVENESS_SUCCESS
        }
    }


    private fun checkCameraType(cameraType: CameraEngineConfig.CameraType): CWDefine.CWLDEnumCamType {
        val type = when (cameraType) {
            CameraEngineConfig.CameraType.CLOUD_WALK_OPEN_ALL -> CWDefine.CWLDEnumCamType.CW_CAMERA_OPEN_ALL
            CameraEngineConfig.CameraType.CLOUD_WALK_OPEN_VIS -> CWDefine.CWLDEnumCamType.CW_CAMERA_OPEN_VIS
            CameraEngineConfig.CameraType.CLOUD_WALK_OPEN_NIS -> CWDefine.CWLDEnumCamType.CW_CAMERA_OPEN_NIS
            else -> CWDefine.CWLDEnumCamType.CW_CAMERA_OPEN_ALL
        }
        return type
    }

    private fun checkFormatType(formatType: CameraEngineConfig.FormatDataType): CWDefine.CWEnumCameraDataFormat {
        val formatType = when (formatType) {
            CameraEngineConfig.FormatDataType.RGB888 -> CWDefine.CWEnumCameraDataFormat.CW_CAMERA_FRAME_FORMAT_RGB888
            CameraEngineConfig.FormatDataType.YUV420 -> CWDefine.CWEnumCameraDataFormat.CW_CAMERA_FRAME_FORMAT_YUV420
            CameraEngineConfig.FormatDataType.GRAY8 -> CWDefine.CWEnumCameraDataFormat.CW_CAMERA_FRAME_FORMAT_GRAY8
            CameraEngineConfig.FormatDataType.GRAY16 -> CWDefine.CWEnumCameraDataFormat.CW_CAMERA_FRAME_FORMAT_GRAY16
            CameraEngineConfig.FormatDataType.GRAY16_8 -> CWDefine.CWEnumCameraDataFormat.CW_CAMERA_FRAME_FORMAT_GRAY16_8
            else -> CWDefine.CWEnumCameraDataFormat.CW_CAMERA_FRAME_FORMAT_RGB888
        }
        return formatType
    }

    private fun checkImgType(imageType: CameraEngineConfig.CaptureImageFormat): CWDefine.CWEnumImageFormat {
        val imgType = when (imageType) {
            CameraEngineConfig.CaptureImageFormat.FORMAT_RAW -> CWDefine.CWEnumImageFormat.CW_IMAGE_FORMAT_RAW
            CameraEngineConfig.CaptureImageFormat.FORMAT_JPG -> CWDefine.CWEnumImageFormat.CW_IMAGE_FORMAT_JPG
            CameraEngineConfig.CaptureImageFormat.FORMAT_PNG -> CWDefine.CWEnumImageFormat.CW_IMAGE_FORMAT_PNG
            CameraEngineConfig.CaptureImageFormat.FORMAT_BMP -> CWDefine.CWEnumImageFormat.CW_IMAGE_FORMAT_BMP
            else -> CWDefine.CWEnumImageFormat.CW_IMAGE_FORMAT_RAW
        }
        return imgType
    }


    fun logMessage(method: String, msg: Any) {
        logError("云丛摄像头${method}方法调用,错误码${msg}")
        logger?.i("云丛摄像头${method}方法调用,错误码${msg}")
    }

}